package com.bill.messages;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
 
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class MessageService implements MessageServiceInterface {
private MessageServiceProperties properties;
private Multipart multipart;
private MimeMessage message;
private String from;
private List<String> to=new ArrayList<String>();
private List<String> bcc=new ArrayList<String>();
private List<String> cc=new ArrayList<String>();
private List<String> replyto=new ArrayList<String>();

public List<String> getReplyto() {
	return replyto;
}

public void setReplyto(List<String> replyto) {
	this.replyto .addAll( replyto);
}

public void setReplyto(String replyto) {
	this.replyto .add( replyto);
}

private String subject;
public List<String> getBcc() {
	return bcc;
}

public void setBcc(List<String> bcc) {
	this.bcc.addAll( bcc);
}
public void setBcc( String bcc) {
	this.bcc.add( bcc);
}

public List<String> getCc() {
	return cc;
}

public void setCc(List<String> cc) {
	this.cc.addAll(cc);
}
public void setCc( String  cc) {
	this.cc .add(cc);
}

private int priority;
private List<String> attachFiles;
protected boolean isconfigured=false;
private String messagecontent;
private String mimetype="text/html";

public MessageService() {
	super();
	//this.properties=new Properties();
	this.multipart=new MimeMultipart();
	//this.message=new MimeMessage();
	
	// TODO Auto-generated constructor stub
}

public void configure(){
	if(isconfigured)return;
	this.message=new MimeMessage(getSession());
	this.isconfigured=true;
}
public MessageService(MessageServiceProperties properties, Multipart multipart,
		MimeMessage message) {
	super();
	this.properties = properties;
	this.multipart = multipart;
	this.message = message;
	 
}
public  Session getSession(){
	return  Session.getDefaultInstance(properties,
			new javax.mail.Authenticator() {
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(properties.getUsername(),properties.getPassword());
				}
			});
}
 public void setAttachFile(String file) 
{
	addAttachFile(new File(file.trim()));
}
public void setAttachFiles(List<String> files) 
{
	for (int i = 0; i < files.size(); i++) {
		files.set(i, files.get(i).trim());
		setAttachFile(files.get(i) );
	}
	this.attachFiles=files;
}
public  List<String> getAttachFiles( ) 
{return this.attachFiles ;
	 
}
public void addAttachFile(File file) {
		// TODO Auto-generated method stub
		BodyPart messageBodyPart = new MimeBodyPart();
		DataSource source = new FileDataSource(file);
		try {
			messageBodyPart.setDataHandler(new DataHandler(source));
			 messageBodyPart.setFileName(file.getName());
			 
			 multipart.addBodyPart(messageBodyPart);
			/* this.attachFiles.add(
					 file.getAbsolutePath()
					 );*/
			// System.out.println("adding attache file:"+file+":"+(new File(file.toString())).exists());
		} catch (MessagingException e) {
			
			//TODO Auto-generated catch block
			e.printStackTrace();
			
		}
		
	}

	public void addAttachFile(File... file) {
		// TODO Auto-generated method stub
for (File file2 : file) {
	addAttachFile(file2);
}
	}
	public void addMessageContentFromFile(File f,String mimetype) {
		setMimetype(mimetype);
		addMessageContentFromFile(f);
	}
	public void addMessageContentFromFile(File f) {
		// TODO Auto-generated method stub
		try {
			BufferedReader reader=new BufferedReader(new InputStreamReader(new FileInputStream(f)));
			String content="";
			String tmp=null;
			while(null!=(tmp=reader.readLine())){
				content+=tmp;
				System.out.println(tmp);
			}
			//System.out.println("message content:"+content);
			 setMessageContent(content );
			 
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void addMessageContentFromFile(String f,String mimetype) {
		setMimetype(mimetype);
		addMessageContentFromFile(f);
	}
	public void addMessageContentFromFile(String f) {
		// TODO Auto-generated method stub
		addMessageContentFromFile(new File(f.trim()));
	}
	public void setMessageContentFromUrls(String mimetype,String ...url){
		setMimetype(mimetype);
		setMessageContentFromUrls(url);
	}
	public void setMessageContentFromUrls(String ...url){
		//URL[] urls=new URL[url.length];
		for(int i=0;i<url.length;i++)
			setMessageContentFromUrl(url[i].trim());
		
	}
	 
	public void setMessageContentFromUrl(URL url,String mimetype){
		setMimetype(mimetype);
		setMessageContentFromUrl(url);
	}

		
	public void setMessageContentFromUrl(URL url){
		try {
			BufferedReader r=new BufferedReader(new InputStreamReader(url.openStream()));
			String mes="";
			String tmp=null;
			while(null!=(tmp=r.readLine()))
			{
				mes+=tmp;
				System.out.println(tmp);
			}
			BodyPart messageBodyPart = new MimeBodyPart();
			//DataSource source = new StringDDataSource(file);
			try {
				//messageBodyPart.setDataHandler(new DataHandler(source));
				// messageBodyPart.setFileName(file.getName());
				messageBodyPart.setContent( mes,mimetype);
				 multipart.addBodyPart(messageBodyPart);
				/* this.attachFiles.add(
						 file.getAbsolutePath()
						 );*/
				// System.out.println("adding attache file:"+file+":"+(new File(file.toString())).exists());
			} catch (MessagingException e) {
				
				//TODO Auto-generated catch block
				e.printStackTrace();
				
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
public void setMessageContentFromUrl(String url){
	try {
		setMessageContentFromUrl(new URL(url));
	} catch (MalformedURLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	}
public void setMessageContentFromUrl(String url,String mimetype){
	setMimetype(mimetype);
	setMessageContentFromUrl(url);
	}
public void setMessageContent(String messag,String mimetype){
	setMimetype(mimetype);
	setMessageContent(messag);
	
}
	public void setMessageContent(String messag){
		//if(!isconfigured)
			//configure();
		//message.setText(messag, "UTF-8");
		messagecontent=messag;
		BodyPart messageBodyPart = new MimeBodyPart();
		//DataSource source = new StringDDataSource(file);
		try {
			//messageBodyPart.setDataHandler(new DataHandler(source));
			// messageBodyPart.setFileName(file.getName());
			messageBodyPart.setContent( messag,mimetype);
			 multipart.addBodyPart(messageBodyPart);
			/* this.attachFiles.add(
					 file.getAbsolutePath()
					 );*/
			// System.out.println("adding attache file:"+file+":"+(new File(file.toString())).exists());
		} catch (MessagingException e) {
			
			//TODO Auto-generated catch block
			e.printStackTrace();
			
		}
		//System.out.println(messag);
	}
	public void setMessageContentFromFile(String file){
		 addMessageContentFromFile(file);
	}
	public void setMessageContentFromFile(String file,String mimetype){
		setMimetype(mimetype);
		setMessageContentFromFile(file);
	}
	
	/**
	 * @return the properties
	 */
	public MessageServiceProperties getProperties() {
		return properties;
	}
	/**
	 * @param properties the properties to set
	 */
	public void setProperties(MessageServiceProperties properties) {
		this.properties = properties;
	}
	/**
	 * @return the multipart
	 */
	public Multipart getMultipart() {
		return multipart;
	}
	/**
	 * @param multipart the multipart to set
	 */
	public void setMultipart(Multipart multipart) {
		this.multipart = multipart;
	}
	/**
	 * @return the message
	 */
	public MimeMessage getMessage() {
		return message;
	}
	/**
	 * @param message the message to set
	 */
	public void setMessage(MimeMessage message) {
		this.message = message;
	}

	/**
	 * @return the from
	 */
	public String getFrom() {
		return from;
	}

	/**
	 * @param from the from to set
	 */
	public void setFrom(String from) {
		this.from = from;
	}

	/**
	 * @return the to
	 */
	public List<String> getTo() {
		return to;
	}

	/**
	 * @param to the to to set
	 */
	public void setTo(List<String> to) {
		this.to .addAll( to);
	}
	public void setTo( String to) {
		this.to .add( to);
	}

	/**
	 * @return the subject
	 */
	public String getSubject() {
		return subject;
	}

	/**
	 * @param subject the subject to set
	 */
	public void setSubject(String subject) {
		this.subject = subject;
	}

	/**
	 * @return the priority
	 */
	public int getPriority() {
		return priority;
	}

	/**
	 * @param priority the priority to set
	 */
	public void setPriority(int priority) {
		this.priority = priority;
	}

	/**
	 * @return the isconfigured
	 */
	public boolean isIsconfigured() {
		return isconfigured;
	}

	/**
	 * @param isconfigured the isconfigured to set
	 */
	public void setIsconfigured(boolean isconfigured) {
		this.isconfigured = isconfigured;
	}
	public void send(){
		if(!isconfigured)
			configure();
		try {
			message.setContent(multipart);
			 
			MessageDigest d=MessageDigest.getInstance("MD5");
			String id=new String( (((long)(Math.random()*Long.MAX_VALUE)+"").getBytes()));
			System.out.println("message id="+id);
			 message.setContentID(id);
			 message.setSentDate(new Date());
			 InternetAddress fr = new InternetAddress(getFrom());
			 message.setFrom(fr);
			 message.setSubject(subject, "UTF-8");
			 
			 System.out.println("from:"+fr);
			  List<String> tos = this.getTo();
			  for (String string : tos) {
				  InternetAddress toss = new InternetAddress(string);
				  message.setRecipient(javax.mail.Message.RecipientType.TO,
							toss);
				  System.out.println("to:"+toss);
			}
			  for (String string : bcc) {
				  InternetAddress toss = new InternetAddress(string);
				  message.setRecipient(javax.mail.Message.RecipientType.BCC,
							toss);
				  System.out.println("BCC:"+toss);
			}
			  for (String string : cc) {
				  InternetAddress toss = new InternetAddress(string);
				  message.setRecipient(javax.mail.Message.RecipientType.CC,
							toss);
				  System.out.println("CC:"+toss);
			}
			  if(null!=replyto&&replyto.size()>0){
			  Address[] adr=new Address[replyto.size()];
			  int i=0;
			  for (String string : replyto) {
				  InternetAddress toss = new InternetAddress(string);
				  adr[i++]=toss;
				  
				  System.out.println("replyto:"+toss);
			}
			  message.setReplyTo(adr);
		  }
			  
			  Transport.send(message);
			  System.out.println(message);
		} catch (MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "MessageService [properties=" + properties + ", multipart="
				+ multipart + ", message=" + message + ", from=" + from
				+ ", to=" + to + ", subject=" + subject + ", priority="
				+ priority + ", isconfigured=" + isconfigured + "]";
	}

	/**
	 * @return the messagecontent
	 */
	public String getMessagecontent() {
		return messagecontent;
	}

	/**
	 * @param messagecontent the messagecontent to set
	 */
	public void setMessagecontent(String messagecontent) {
		this.messagecontent = messagecontent;
	}

	/**
	 * @return the mimetype
	 */
	public String getMimetype() {
		return mimetype;
	}

	/**
	 * @param mimetype the mimetype to set
	 */
	public void setMimetype(String mimetype) {
		this.mimetype = mimetype;
	}

}
